/*
 * app_hub_api_usart_event.c
 *
 *  Created on: 2023年7月25日
 *      Author: HXF
 */

#include "app_hub_api_usart_event.h"
#include "app_hub_api_rf_event.h"
#include "string.h"
#include "stdbool.h"
#include "app_log.h"
#include "device.h"
#include "bsp_usart.h"
#include "app_api.h"
#include "net_aseq.h"
#include "RBFVersion.h"
#include "app_filetransport_api_subsidiary.h"
#include "bsp_rf.h"
#include "app_broadcast_retry.h"
#include "device_nvm.h"
#include "device_rfmid.h"
#include "device_partition.h"

#define HUB_API_WEAK  __attribute__((weak))

#define USART_IDLE_TIMEOUT_MS (1638) // 50MS = 32768/20

static int rcv_data_len = 0;
static unsigned char rcv_crc_len = 0;

static unsigned char ack_msg[HUB_API_USART_MSG_DATA_MAX_LEN] = {0};
static int ack_msg_len = 0;
#ifdef BSP_ENABLE_COM
static hub_api_usart_msg_t listen_pkt = {0};

static unsigned char usart_tx_buffer[HUB_API_USART_MSG_MAX_LEN] = {0};
static int usart_tx_len = 0;
#endif
static long pkt_rx_count = 0;
static long pkt_tx_count = 0;
static unsigned char init_reboot = 0;

typedef enum{
  STEP_STX,
  STEP_SEQ,
  STEP_LEN,
  STEP_STATU,
  STEP_FCODE,
  STEP_DATA,
  STEP_CRC,
  STEP_ETX,
}PARSE_STEP_E;

static PARSE_STEP_E step = STEP_STX;

const hub_api_usart_rx_entry_t ds_hub_api_rx_fcode_table[] ={
    {P_TO_H_SET_INIT, rx_set_init},
    {P_TO_H_SET_RFM_QRFH, rx_set_rfm_qrfh},
    {P_TO_H_SET_RFM_QRFH_BATCH, rx_set_rfm_qrfh_batch},
    {P_TO_H_SET_RFM_STATUS_MODEL, rx_set_rfm_status_model},
    {P_TO_H_SET_RFM_OPERATE_MODEL, rx_set_rfm_operate_model},
    {P_TO_H_SET_RFM_SYNC_OPTION_BATCH, rx_set_rfm_sync_option_batch},
    {P_TO_H_SET_RFM_SYNC_QRFH_BATCH, rx_set_rfm_sync_qrfh_batch},
    {P_TO_H_SET_HUB_RESET, rx_set_hub_reset},

    {P_TO_H_GET_REGISTERED_RFM_INFO, rx_get_registered_rfm_info},
    {P_TO_H_GET_SPECIFIC_RFM_INFO, rx_get_specific_rfm_info},
    {P_TO_H_GET_HUB_PHYSICAL, rx_get_hub_physical},
    {P_TO_H_GET_HUB_RSSI, rx_get_hub_rssi},
    {P_TO_H_GET_HUB_VER, rx_get_hub_ver},

    {P_TO_H_DO_LOCAL_REGISTER, rx_do_local_register},
    {P_TO_H_DO_MAC_REGISTER, rx_do_mac_register},
    {P_TO_H_DO_QRCODE_REGISTER, rx_do_qrcode_register},
    {P_TO_H_DO_SYNC_BROADCAST, rx_do_sync_broadcast},
    {P_TO_H_DO_NORMAL_BROADCAST, rx_do_normal_broadcast},
    {P_TO_H_DO_POINT_TO_POINT, rx_do_point_to_point},
    {P_TO_H_DO_DELETE_RFM, rx_do_delete_rfm},
    {P_TO_H_DO_START_OTA, rx_do_start_ota},
    {P_TO_H_DO_SN_REGISTER, rx_do_sn_register},
    {P_TO_H_DO_FILE_TRANSPORT, rx_do_file_transport},
    {P_TO_H_DO_CHOOSE_ANT, rx_do_choose_ant},
    {P_TO_H_DO_STOP_SYNC_BROADCAST, rx_do_stop_sync_broadcast},
    {P_TO_H_DO_TEST, rx_do_test},

    {H_TO_P_EVENT_HUB_EVENT, rx_event_hub_event},
    {H_TO_P_EVENT_RFM_EVENT, rx_event_rfm_event},
    {H_TO_P_EVENT_FILE_TRANSFER, rx_event_file_transfer},
    {H_TO_P_EVENT_RFM_DEBUG_EVENT, rx_event_rfm_debug_event},
};

#define usart_rx_cmd_num (sizeof(ds_hub_api_rx_fcode_table)/sizeof(ds_hub_api_rx_fcode_table[0]))

void DS_hub_api_usart_listen(void)
{
#ifdef BSP_ENABLE_COM

  unsigned int iret = 0;
  unsigned char *data=NULL;
  if(bufferIsEmpty(&com_RXBuff) != true){
      data = bufferRemove(&com_RXBuff);
      iret = DS_hub_api_usart_msg_parse(data[0], &listen_pkt);
      if(iret == 0){
          DS_hub_api_creat_usart_rx_event(&listen_pkt);
      }else{
          if(iret != 1){
              //if(hub_log_enable){
                  DS_app_log_error("parse error %x\r\n",iret);
              //}
          }
      }
  }
#endif
}


int DS_hub_api_push_usart_rx_event(void *msg, int len)
{
  int iret = DS_app_hub_api_usart_rx_event_link_push(msg, len);
  if(iret){
  }
  return iret;
}

int DS_hub_api_creat_usart_rx_event(const hub_api_usart_msg_t *ptr_pkt)
{
  unsigned char msg[HUB_API_USART_MSG_MAX_LEN] = {0};
  int len = 0;
  int i = 0;

  msg[len++] = ptr_pkt->stx;
  msg[len++] = ptr_pkt->seq;
  msg[len++] = ptr_pkt->len;
  msg[len++] = ptr_pkt->statu;
  msg[len++] = ptr_pkt->fcode;
  for(i = 0; i < (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE); i++){
      msg[len++] = ptr_pkt->data.data[i];
  }
  msg[len++] = ptr_pkt->crc[0];
  msg[len++] = ptr_pkt->crc[1];
  msg[len++] = ptr_pkt->etx;

  return DS_hub_api_push_usart_rx_event((unsigned char *)msg, len);
}


int DS_hub_api_pop_usart_rx_event(void *msg, int *ptr_len)
{
  int iret = DS_app_hub_api_usart_rx_event_link_pop(msg, ptr_len);
  if(iret){
  }
  return iret;
}

int DS_hub_api_get_usart_rx_event(hub_api_rx_evt_t *ptr_pkt)
{
  unsigned char msg[HUB_API_USART_MSG_MAX_LEN] = {0};
  int len = 0;
  int i = 0;
  int idx = 0;

  if(DS_hub_api_pop_usart_rx_event((unsigned char *)msg, &len)){
      return 1;
  }
  if(!len  || len < 8){
      return 1;
  }
  if((msg[2] + 4) != len){
      return 1;
  }
  ptr_pkt->channel = EVT_USART_RX;

  ptr_pkt->msg.usart_msg.stx = msg[idx++];
  ptr_pkt->msg.usart_msg.seq = msg[idx++];
  ptr_pkt->msg.usart_msg.len = msg[idx++];
  ptr_pkt->msg.usart_msg.statu = msg[idx++];
  ptr_pkt->msg.usart_msg.fcode = msg[idx++];

  for(i = 0; i < (ptr_pkt->msg.usart_msg.len - HUB_API_USART_MSG_LEN_MIN_VALUE); i++){
      ptr_pkt->msg.usart_msg.data.data[i] = msg[idx++];
  }
  ptr_pkt->msg.usart_msg.crc[0] = msg[idx++];
  ptr_pkt->msg.usart_msg.crc[1] = msg[idx++];
  ptr_pkt->msg.usart_msg.etx = msg[idx++];
  return 0;
}

static unsigned char packet_add_seq_byte(void)
{
  unsigned char ret_seq = 0;
  unsigned char hub_seq = 0;
  getThisParam(ENbyHubUsartSeq, (unsigned char *)&hub_seq);
  ret_seq = hub_seq;
  hub_seq++;
  hub_seq %= 0xff;
  if(hub_seq == 0 || hub_seq == 1){
      hub_seq = 2;
  }
  setThisParam(ENbyHubUsartSeq, (unsigned char *)&hub_seq);
  return ret_seq;
}

static unsigned char passive_packet_add_statu_byte(unsigned char error_code)
{
  unsigned char statu = 0;
  unsigned char bcast_busy = 0;
  unsigned char cfg_req = 0;

  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  getThisParam(ENbyCfgReq, (unsigned char *)&cfg_req);
  if(error_code != NO_ERROR){
      HUB_API_SET_BIT(statu, 7);
  }
  if(bcast_busy){
      HUB_API_SET_BIT(statu, 1);
  }
  if(cfg_req){
      HUB_API_SET_BIT(statu, 0);
  }
  return statu;
}

static int pack_passive_usart_packet(HUB_API_USART_MSG_FCODE_E fcode, unsigned char error_code,
                              unsigned char *msg,  int msg_len,
                              hub_api_usart_msg_t *pkt)
{
  unsigned short crc_value;
  memset((char *)pkt, 0, sizeof(hub_api_usart_msg_t));
  pkt->stx = 0x02;

  pkt->len = 0;
  pkt->seq = packet_add_seq_byte();
  pkt->statu = passive_packet_add_statu_byte(error_code);
  pkt->fcode = fcode;
  memcpy(&pkt->data.data, msg, msg_len);
  pkt->len = HUB_API_USART_MSG_LEN_MIN_VALUE + msg_len;
  crc_value = B_L_SWAP_16(get_msg_crc16(&pkt->len, pkt->len + 1 -2));
  pkt->crc[0] = (crc_value >> 8) & 0xff;
  pkt->crc[1] = (crc_value) & 0xff;
  pkt->etx = 0x03;

  printf_pkt(pkt);

  return 0;
}

static int pack_err_packrt_usart_packet(HUB_API_USART_MSG_FCODE_E fcode, unsigned char error_code,
                                        hub_api_usart_msg_t *pkt)
{
  unsigned short crc_value;
  memset((char *)pkt, 0, sizeof(hub_api_usart_msg_t));
  pkt->stx = 0x02;

  pkt->len = 0;
  pkt->seq = packet_add_seq_byte();
  pkt->statu = passive_packet_add_statu_byte(error_code);
  pkt->fcode = fcode;
  pkt->data.rx_usart_error_code_data.error_code = error_code;
  pkt->len = 5;
  crc_value = B_L_SWAP_16(get_msg_crc16(&pkt->len, pkt->len + 1 -2));
  pkt->crc[0] = (crc_value >> 8) & 0xff;
  pkt->crc[1] = (crc_value) & 0xff;
  pkt->etx = 0x03;

  printf_pkt(pkt);

  return 0;
}

static void DS_hub_api_pkt_clean(hub_api_usart_msg_t *ptr_pkt)
{
  memset(ptr_pkt, 0, sizeof(hub_api_usart_msg_t));
}

void DS_hub_api_usart_msg_parse_init(void)
{
  step = STEP_STX;
}

/**
 * @brief DS_hub_api_usart_msg_parse 串口报文解析函数
 * //STX SEQ LEN STATU FCODE DATA CRC ETX
 * //0x02                             0x03
 * @param data，com串口收到的字节
 *        pkt 解析之后的报文结构体
 * @return 0 解析成功； 1 正在解析；2 LEN的内容错误； 3 CRC错误； 4 帧尾错误； 5 seq重复
 */

//还需要增加超时退出机制
int DS_hub_api_usart_msg_parse(unsigned char data, hub_api_usart_msg_t *ptr_pkt)
{
  int iret = 1;
  unsigned char seq = 0;

  switch(step){
    case STEP_STX:
      if(data == 0x02){
          DS_hub_api_pkt_clean(ptr_pkt);
          ptr_pkt->stx = data;
          step = STEP_SEQ;
          restart_usart_idle_Timer(USART_IDLE_TIMEOUT_MS, NULL);
      }
      break;
    case STEP_SEQ:
      ptr_pkt->seq = data;
      step = STEP_LEN;
      break;
    case STEP_LEN:
      if(data < HUB_API_USART_MSG_LEN_MIN_VALUE || data > HUB_API_USART_MSG_LEN_MAX_VALUE){
          iret = 2;
          step = STEP_STX;
          break;
      }
      ptr_pkt->len = data;
      step = STEP_STATU;
      break;
    case STEP_STATU:
      ptr_pkt->statu = data;
      step = STEP_FCODE;
      break;
    case STEP_FCODE:
      ptr_pkt->fcode = data;
      rcv_data_len = 0;
      rcv_crc_len = 0;
      step = (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE) ? STEP_DATA : STEP_CRC;
      break;
    case STEP_DATA:
      ptr_pkt->data.data[rcv_data_len++] = data;
      if(rcv_data_len == ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE){
          step = STEP_CRC;
      }
      break;
    case STEP_CRC:
      ptr_pkt->crc[rcv_crc_len++] = data;
      if(rcv_crc_len == 2){
          step = STEP_ETX;
      }
      break;
    case STEP_ETX:
      stop_usart_idle_Timer(NULL);
      if(data != 0x03){
          iret = 4;
          step = STEP_STX;
          break;
      }else{
          //crc16计算出来的crc值，转成大端模式
          if((ptr_pkt->crc[0] << 8 | ptr_pkt->crc[1]) ==
              B_L_SWAP_16(get_msg_crc16(&ptr_pkt->len, ptr_pkt->len + 1 - 2))){

          }else{
              iret = 3;
              step = STEP_STX;
              break;
          }
      }
      ptr_pkt->etx = data;

      getThisParam(ENbyPanelUsartSeq, (unsigned char *)&seq);
      if(ptr_pkt->seq == seq){
          iret = 5;
          DS_app_log_error("same seq %02x, fcode %02x\r\n",ptr_pkt->seq,ptr_pkt->fcode);
      }else{
          iret = 0;
          if(hub_log_enable){
              pkt_rx_count++;
              DS_app_log_error("rx pkt %ld, seq %02x fcode %02x\r\n",pkt_rx_count, ptr_pkt->seq, ptr_pkt->fcode);
          }
          setThisParam(ENbyPanelUsartSeq, (unsigned char *)&ptr_pkt->seq);
      }
#if(0)
      if(hub_log_enable){
          if(ptr_pkt->fcode == 0x63 || ptr_pkt->fcode == 0x65){
              DS_app_log_hexdump_error("panel: ",ptr_pkt->data.data,(ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
          }
      }
#endif
      step = STEP_STX;
      break;
    default:
      step = STEP_STX;
      break;
  }
  if(iret == 3){
      pack_err_packrt_usart_packet(ptr_pkt->fcode,PKT_CRC16_ERROR,
                                   ptr_pkt);
      DS_hub_api_creat_passive_usart_ack(ptr_pkt);
  }
  return iret;
}

int DS_hub_api_usart_rx_event_mediator(const hub_api_usart_msg_t *ptr_pkt,
                                       hub_api_usart_msg_t *ptr_ack_pkt)
{
  if(!ptr_pkt){
      return 1;
  }

  unsigned int i = 0;
  for(i = 0; i < usart_rx_cmd_num; i++){
      if(ds_hub_api_rx_fcode_table[i].fcode == ptr_pkt->fcode){
          break;
      }
  }

  if(i == usart_rx_cmd_num){
      return 2;
  }

  ds_hub_api_rx_fcode_table[i].fun(ptr_pkt, ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_set_init(const hub_api_usart_msg_t *ptr_pkt,
                             hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char cfg_req = 0;
#if(HUB_NEWVER_USE)
  unsigned char reset_mode = SOFT_RESET;
#endif
  switch(ptr_pkt->data.rx_set_init_data.freq){
    case RF_FREQ_868MHZ:
    case RF_FREQ_915MHZ:
    case RF_FREQ_433MHZ:
    case RF_FREQ_915MHZ_RCM:
    case RF_FREQ_868MHZ_WPC:
#if(HUB_NEWVER_USE)  //该功能需要与panel版本保持一致，因为枚举定义新旧版本不兼容
      if(ptr_pkt->data.rx_set_init_data.freq != getDeviceRfFreq()){
          setDeviceRfFreq(ptr_pkt->data.rx_set_init_data.freq);
          init_reboot = 1;
          setThisParam(ENbyResetMode, (unsigned char *)&reset_mode);
      }
#endif
      break;
    case RF_FREQ_MAX:
      //暂不支持
      break;
    default:
      err_code = PARAMETER_ERROR;
      goto ack;
      break;
  }

  setThisParam(ENbyjamming, (unsigned char *)&ptr_pkt->data.rx_set_init_data.jamming_th);
  setThisParam(ENbycustcode, (unsigned char *)&ptr_pkt->data.rx_set_init_data.cust_code);

  setThisParam(ENbyCfgReq, (unsigned char *)&cfg_req); //收到初始化信息

ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_set_rfm_qrfh(const hub_api_usart_msg_t *ptr_pkt,
                                 hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char rfmid = get_rfmid_from_catno(
      ptr_pkt->data.rx_set_rfm_qrfh_data.cat_type,
      ptr_pkt->data.rx_set_rfm_qrfh_data.no);

  if(rfmid ==  0xff){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if(!check_rfmid_is_registered(rfmid)){
      err_code = NOREGISTER_ERROR;
      goto ack;
  }

  setDeviceParam(rfmid, ENpbyNodeQrfH1First, (unsigned char *)&ptr_pkt->data.rx_set_rfm_qrfh_data.qrfh1);
  setDeviceParam(rfmid, ENpbyNodeQrfH2First, (unsigned char *)&ptr_pkt->data.rx_set_rfm_qrfh_data.qrfh2);

ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                          &err_code, 1,
                          ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_set_rfm_qrfh_batch(const hub_api_usart_msg_t *ptr_pkt,
                                       hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  //unsigned char ioen_lock = 0;
  //unsigned char need_unlock = 0;
  unsigned char rfmid = 0xff;
  unsigned char qrfh1 = 0;
  unsigned char qrfh2 = 0;
  int i= 0;
  unsigned char bitmask = 0;
  int bitmask_byte = 0;
  int cat_no_max = 0;
  unsigned char data_idx = 0;
  unsigned char bit_idx = 0;
  if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.cat_type == CAT_IO){
      bitmask_byte = CAT_IO_BITMASK_BYTE;
      cat_no_max = DEVICE_TYPE_IO_CN;
  }else if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.cat_type == CAT_SOUNDER){
      bitmask_byte = CAT_SOUNDER_BITMASK_BYTE;
      cat_no_max = DEVICE_TYPE_SOUNDER_CN;
  }else if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.cat_type == CAT_KEYPAD){
      bitmask_byte = CAT_KEYPAD_BITMASK_BYTE;
      cat_no_max = DEVICE_TYPE_KEYPAD_CN;
  }else if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.cat_type == CAT_FOB){
      bitmask_byte = CAT_FOB_BITMASK_BYTE;
      cat_no_max = DEVICE_TYPE_FOB_CN;
  }else{
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  if(ptr_pkt->len != (2+bitmask_byte+HUB_API_USART_MSG_LEN_MIN_VALUE)){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.qrf_bit_idx > 15){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  //if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.cat_type == CAT_IO){
  //    if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.qrf_bit_idx == 7){
  //        need_unlock = 1;  //批量对IOEN进行操作
  //    }
  //}
  for(i = 0; i < cat_no_max; i++){
      data_idx = bitmask_byte - i/8 - 1;
      bit_idx = i%8;
      bitmask = HUB_API_GET_BIT(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.bit_mask[data_idx],
                                bit_idx);
      rfmid = get_rfmid_from_catno(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.cat_type
                                   , i);
      //if(need_unlock){
      //    setDeviceParam(rfmid, ENbyIOenLock, &ioen_lock);
      //}
      if(ptr_pkt->data.rx_set_rfm_qrfh_batch_data.qrf_bit_idx < 8){
          qrfh1 = 0;
          if(getDeviceParam(rfmid ,ENpbyNodeQrfH1First, (unsigned char *)&qrfh1)){
              if(hub_log_enable){
                  DS_app_log_debug("key %d use default value %x\r\n",rfmid+ENpbyNodeQrfH1First, qrfh1);
              }
          }
          if(bitmask){
              HUB_API_SET_BIT(qrfh1, ptr_pkt->data.rx_set_rfm_qrfh_batch_data.qrf_bit_idx);
          }else{
              HUB_API_CLEAN_BIT(qrfh1, ptr_pkt->data.rx_set_rfm_qrfh_batch_data.qrf_bit_idx);
          }
          setDeviceParam(rfmid, ENpbyNodeQrfH1First, (unsigned char *)&qrfh1);
          if(hub_log_enable){
              APP_PRINTF("rfmid %d: bitmask(%d) qrfh1 (%x)\r\n",rfmid,bitmask,qrfh1);
          }
      }else{
          qrfh2 = 0;
          if(getDeviceParam(rfmid ,ENpbyNodeQrfH2First, (unsigned char *)&qrfh2)){
              if(hub_log_enable){
                  DS_app_log_debug("key %d use default value %x\r\n",rfmid+ENpbyNodeQrfH2First, qrfh2);
              }
          }
          if(bitmask){
              HUB_API_SET_BIT(qrfh2, (ptr_pkt->data.rx_set_rfm_qrfh_batch_data.qrf_bit_idx - 8));
          }else{
              HUB_API_CLEAN_BIT(qrfh2, (ptr_pkt->data.rx_set_rfm_qrfh_batch_data.qrf_bit_idx - 8));
          }
          setDeviceParam(rfmid, ENpbyNodeQrfH2First, (unsigned char *)&qrfh2);
          if(hub_log_enable){
              APP_PRINTF("rfmid %d: bitmask(%d) qrfh2 (%x)\r\n",rfmid,bitmask,qrfh2);
          }
      }
  }

ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                          &err_code, 1,
                          ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_set_rfm_status_model(const hub_api_usart_msg_t *ptr_pkt,
                                         hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char group = 0;
  unsigned char option[OPTION_LENGTH] = {0};
  unsigned char key = 0;
  unsigned char group_flag = 0;
  unsigned char option_flag = 0;
  int i,j,len;
  i = j = len = 0;
  unsigned char rfmid = get_rfmid_from_catno(
      ptr_pkt->data.rx_set_rfm_status_model_data.cat_type,
      ptr_pkt->data.rx_set_rfm_status_model_data.no);

  if(rfmid ==  0xff){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  if(!check_rfmid_is_registered(rfmid)){
      err_code = NOREGISTER_ERROR;
      goto ack;
  }

  len = ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE -2;

  while((i + 1) < len){
      key = ptr_pkt->data.rx_set_rfm_status_model_data.key_value[i];
      if(key == GROUP_IDX_KEY){
          group = ptr_pkt->data.rx_set_rfm_status_model_data.key_value[i+1];
          group_flag = 1;
          i = i + 2;
      }else if(key == OPTION_KEY){
          for(j = 0; (j < OPTION_LENGTH) && ((i+1+j) < len); j++){
              option[j] = ptr_pkt->data.rx_set_rfm_status_model_data.key_value[i+1+j];
          }
          option_flag = 1;
          i = i + OPTION_LENGTH + 1;
      }else{
          break;
      }
  }

  if(i != len || !len){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if(group_flag){
      setDeviceParam(rfmid, ENpbyNodeGroupIdxFirst, (unsigned char *)&group);
  }
  if(option_flag){
      setDeviceParam(rfmid, ENpbyNodeOptionFirst, (unsigned char *)option);
  }
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                          &err_code, 1,
                          ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_set_rfm_operate_model(const hub_api_usart_msg_t *ptr_pkt,
                                          hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;

  unsigned char led_ctrl[LEDCTRL_LENGTH] = {0};
  unsigned char led_ctrl_flag = 0;
  unsigned char operate_ctrl[OPERATECTRL_LENGTH] = {0};
  unsigned char operate_flag = 0;
  unsigned char key_value = 0;
  unsigned char key_value_flag = 0;


  unsigned char key = 0;
  int i,j,len;
  i = j = len = 0;
  unsigned char rfmid = get_rfmid_from_catno(
      ptr_pkt->data.rx_set_rfm_operate_model_data.cat_type,
      ptr_pkt->data.rx_set_rfm_operate_model_data.no);
  if(rfmid ==  0xff){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  if(!check_rfmid_is_registered(rfmid)){
      err_code = NOREGISTER_ERROR;
      goto ack;
  }
  len = ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE -2;

  while(((i + 1) < len)){
        key = ptr_pkt->data.rx_set_rfm_operate_model_data.key_value[i];
        if(key == COMLED_CTRL_KEY){
            getDeviceParam(rfmid ,ENbyLedCtrlFlag, (unsigned char *)&led_ctrl_flag);
            if(0){//if(led_ctrl_flag){
                err_code = RFM_BUSY_ERROR;
                goto ack;
            }
            for(j = 0; (j < 5) && ((i+1+j) < len); j++){  //不再使用LEDCTRL_LENGTH
                led_ctrl[j+1] = ptr_pkt->data.rx_set_rfm_operate_model_data.key_value[i+1+j]; //空出第一个字节
            }
            if(j == 5){  //不再使用LEDCTRL_LENGTH
                led_ctrl_flag = 1;
            }else{
                err_code = PARAMETER_ERROR;
                goto ack;
            }
            i = i + 5 + 1;  //不再使用LEDCTRL_LENGTH
        }else if(key == KEYVALUE_GET_KEY){
            getDeviceParam(rfmid ,ENbyKeyValueGetFlag, (unsigned char *)&key_value_flag);
            if(0){//if(key_value_flag){
                err_code = RFM_BUSY_ERROR;
                goto ack;
            }
            key_value = ptr_pkt->data.rx_set_rfm_operate_model_data.key_value[i+1];
            key_value_flag = 1;
            i = i + 2;
        }else if(key == OPERATE_CTRL_KEY){
            for(j = 0; (j < 3) && ((i+1+j) < len); j++){ //不再使用OPERATECTRL_LENGTH
                operate_ctrl[j+1] = ptr_pkt->data.rx_set_rfm_operate_model_data.key_value[i+1+j]; //空出第一个字节
            }
            if(j == 3){
                operate_flag = 1;
            }else{
                err_code = PARAMETER_ERROR;
                goto ack;
            }
            i = i + 3 + 1;  //不再使用OPERATECTRL_LENGTH
        }
        else{
            break;
        }
    }

  if(i != len || !len){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  if(led_ctrl_flag){
      setDeviceParam(rfmid, ENbyLedCtrl, (unsigned char *)led_ctrl);
      setDeviceParam(rfmid, ENbyLedCtrlFlag, (unsigned char *)&led_ctrl_flag);
      updata_node_aseq(ASEQ_LED, rfmid);
      led_ctrl[0] = get_node_aseq(ASEQ_LED, rfmid);
  }
  if(key_value_flag){
      setDeviceParam(rfmid, ENbyKeyValueGet, (unsigned char *)&key_value);
      setDeviceParam(rfmid, ENbyKeyValueGetFlag, (unsigned char *)&key_value_flag);
  }
  if(operate_flag){
      setDeviceParam(rfmid, ENbyOperateCtrl, (unsigned char *)operate_ctrl);
      setDeviceParam(rfmid, ENbyOperateCtrlFlag, (unsigned char *)&operate_flag);
      updata_node_aseq(ASEQ_OPERATE, rfmid);
      operate_ctrl[0] = get_node_aseq(ASEQ_OPERATE, rfmid);
  }
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                          &err_code, 1,
                          ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_set_rfm_sync_option_batch(const hub_api_usart_msg_t *ptr_pkt,
                                         hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char rfmid = 0;
  unsigned char rfm_num = 0;
  unsigned char cat = 0;
  unsigned char no = 0;
  unsigned char panel_option[OPTION_LENGTH] ={0};
  unsigned char hub_option[OPTION_LENGTH] ={0};

  int i = 0;

  if(ptr_pkt->len < 10){ //4+1+5*n
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  rfm_num = ptr_pkt->data.rx_set_rfm_sync_option_batch_data.number;
  if((ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE - 1) != (rfm_num *5)){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  while(rfm_num){
      cat = ptr_pkt->data.rx_set_rfm_sync_option_batch_data.data[i+0];
      no = ptr_pkt->data.rx_set_rfm_sync_option_batch_data.data[i+1];
      rfmid = get_rfmid_from_catno(cat,no);
      if(rfmid != 0xff){
          panel_option[0] = ptr_pkt->data.rx_set_rfm_sync_option_batch_data.data[i+2];
          panel_option[1] = ptr_pkt->data.rx_set_rfm_sync_option_batch_data.data[i+3];
          panel_option[2] = ptr_pkt->data.rx_set_rfm_sync_option_batch_data.data[i+4];

          getDeviceParam(rfmid, ENpbyNodeOptionFirst, hub_option);
          if(memcmp(hub_option, panel_option, OPTION_LENGTH)){
              DS_app_log_error("rfm:%d,hub[%02x%02x%02x],panel[%02x%02x%02x]",
                               rfmid,hub_option[0],hub_option[1],hub_option[2],
                               panel_option[0],panel_option[1],panel_option[2]);
          }

          if(HUB_SYNC_PRM_SAVE){
              setDeviceParam(rfmid, ENpbyNodeOptionFirst, panel_option);
          }
      }
      i += 5;
      rfm_num--;
  }
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);

  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_set_rfm_sync_qrfh_batch(const hub_api_usart_msg_t *ptr_pkt,
                                            hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char rfmid = 0;
  unsigned char rfm_num = 0;
  unsigned char cat = 0;
  unsigned char no = 0;
  unsigned char panel_qrfh1 = 0;
  unsigned char panel_qrfh2 = 0;
  unsigned char hub_qrfh1 = 0;
  unsigned char hub_qrfh2 = 0;

  int i = 0;

  if(ptr_pkt->len < 9){ //4+1+4*n
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  rfm_num = ptr_pkt->data.rx_set_rfm_sync_qrfh_batch_data.number;
  if((ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE - 1) != (rfm_num *4)){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  while(rfm_num){
      cat = ptr_pkt->data.rx_set_rfm_sync_qrfh_batch_data.data[i+0];
      no = ptr_pkt->data.rx_set_rfm_sync_qrfh_batch_data.data[i+1];
      rfmid = get_rfmid_from_catno(cat,no);
      if(rfmid != 0xff){
          panel_qrfh1 = ptr_pkt->data.rx_set_rfm_sync_qrfh_batch_data.data[i+2];
          panel_qrfh2 = ptr_pkt->data.rx_set_rfm_sync_qrfh_batch_data.data[i+3];

          getDeviceParam(rfmid, ENpbyNodeQrfH1First, &hub_qrfh1);
          getDeviceParam(rfmid, ENpbyNodeQrfH2First, &hub_qrfh2);
          if(hub_qrfh1 != panel_qrfh1 || hub_qrfh2 != panel_qrfh2){
              DS_app_log_error("rfm:%d,hub[%02x%02x],panel[%02x%02x]",
                               rfmid,hub_qrfh1,hub_qrfh2,
                               panel_qrfh1,panel_qrfh2);
          }

          if(HUB_SYNC_PRM_SAVE){
              setDeviceParam(rfmid, ENpbyNodeQrfH1First, &panel_qrfh1);
              setDeviceParam(rfmid, ENpbyNodeQrfH2First, &panel_qrfh2);
          }
      }
      i += 4;
      rfm_num--;
  }
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);

  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_set_hub_reset(const hub_api_usart_msg_t *ptr_pkt,
                             hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char reset_mode = 0xff;

  reset_mode = ptr_pkt->data.rx_set_hub_reset_data.reset_mode;
  if(reset_mode == SOFT_RESET || reset_mode == XMODEM_RESET){
      setThisParam(ENbyResetMode, (unsigned char *)&reset_mode);
  }else{
      err_code = PARAMETER_ERROR;
  }

#if(0)
  if(err_code != NO_ERROR){
      pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
      DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  }else{
      hub_do_reset();
  }
#else
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
#endif
  return err_code;
}

HUB_API_WEAK int rx_get_registered_rfm_info(const hub_api_usart_msg_t *ptr_pkt,
                                            hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  memset(ack_msg, 0, sizeof(ack_msg));
  ack_msg_len = 0;

#if(0)
  if(ptr_pkt->data.rx_get_registered_rfm_data.cat_type == CAT_IO){
      getThisParam(ENbyCatIORegister, (unsigned char*)ack_msg);
      ack_msg_len = CAT_IO_BITMASK_BYTE;
  }else if(ptr_pkt->data.rx_get_registered_rfm_data.cat_type == CAT_SOUNDER){
      getThisParam(ENbyCatSounderRegister, (unsigned char*)ack_msg);
      ack_msg_len = CAT_SOUNDER_BITMASK_BYTE;
  }else if(ptr_pkt->data.rx_get_registered_rfm_data.cat_type == CAT_KEYPAD){
      getThisParam(ENbyCatKeypadRegister, (unsigned char*)ack_msg);
      ack_msg_len = CAT_KEYPAD_BITMASK_BYTE;
  }else if(ptr_pkt->data.rx_get_registered_rfm_data.cat_type == CAT_FOB){
      getThisParam(ENbyCatKeypobRegister, (unsigned char*)ack_msg);
      ack_msg_len = CAT_FOB_BITMASK_BYTE;
  }else{
      err_code = PARAMETER_ERROR;
      goto ack;
  }
ack:
    if(err_code != NO_ERROR){
        ack_msg[0] = err_code;
        ack_msg_len = 1;
    }
#else
  if(getThisParam(ENbyNodeJoinInfo, (unsigned char*)ack_msg)){
      if(hub_log_enable){
          DS_app_log_error("ENbyNodeJoinInfo get err, use default value\r\n");
      }
  }
  ack_msg_len = NODE_JOIN_INFO_LENGTH;

#endif
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            ack_msg, ack_msg_len,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_get_specific_rfm_info(const hub_api_usart_msg_t *ptr_pkt,
                                          hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char rfmid = get_rfmid_from_catno(
      ptr_pkt->data.rx_get_specific_rfm_info_data.cat_type,
      ptr_pkt->data.rx_get_specific_rfm_info_data.no);

  if(rfmid ==  0xff){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if(!check_rfmid_is_registered(rfmid)){
      err_code = NOREGISTER_ERROR;
      goto ack;
  }

  memset(ack_msg, 0, sizeof(ack_msg));
  if(getDeviceParam(rfmid, ENpbyNodeQrfR1First, (unsigned char *)&ack_msg[0])){
      if(hub_log_enable){
          DS_app_log_debug("key %d use default value %x\r\n",rfmid+ENpbyNodeQrfR1First, ack_msg[0]);
      }
  }
  if(getDeviceParam(rfmid, ENpbyNodeQrfR2First, (unsigned char *)&ack_msg[1])){
      if(hub_log_enable){
          DS_app_log_debug("key %d use default value %x\r\n",rfmid+ENpbyNodeQrfR2First, ack_msg[1]);
      }
  }
  if(getDeviceParam(rfmid, ENpbyNodeQrfH1First, (unsigned char *)&ack_msg[2])){
      if(hub_log_enable){
          DS_app_log_debug("key %d use default value %x\r\n",rfmid+ENpbyNodeQrfH1First, ack_msg[2]);
      }
  }
  if(getDeviceParam(rfmid, ENpbyNodeQrfH2First, (unsigned char *)&ack_msg[3])){
      if(hub_log_enable){
          DS_app_log_debug("key %d use default value %x\r\n",rfmid+ENpbyNodeQrfH2First, ack_msg[3]);
      }
  }
  if(getDeviceParam(rfmid, ENpbyNodeOptionFirst, (unsigned char *)&ack_msg[4])){
      if(hub_log_enable){
          DS_app_log_debug("key %d use default value %02x %02x %02x\r\n",rfmid+ENpbyNodeOptionFirst, ack_msg[4],ack_msg[5],ack_msg[6]);
      }
  }
  ack_msg_len = sizeof(usart_tx_get_specific_rfm_info_data_t);
ack:
  if(err_code != NO_ERROR){
      ack_msg[0] = err_code;
      ack_msg_len = 1;
  }
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            ack_msg, ack_msg_len,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_get_hub_physical(const hub_api_usart_msg_t *ptr_pkt,
                                  hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  (void)ptr_pkt;
  (void)ptr_ack_pkt;

  memset(ack_msg, 0, sizeof(ack_msg));
  get_device_state(ack_msg);
  ack_msg_len = 4;

  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            ack_msg, ack_msg_len,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_get_hub_rssi(const hub_api_usart_msg_t *ptr_pkt,
                                  hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  signed char real_rssi = 0;
  signed char avg_rssi = 0;
  (void)ptr_pkt;
  (void)ptr_ack_pkt;

  memset(ack_msg, 0, sizeof(ack_msg));
  if(getThisParam(ENbyRealRssi, &real_rssi)){
      real_rssi = 0;
  }
  if(getThisParam(ENbyAvgRssi, &avg_rssi)){
      avg_rssi = 0;
  }
  ack_msg[0] = real_rssi + 128; //real_rssi： -128~0，传给LINUX偏移128
  ack_msg[1] = avg_rssi + 128;
  ack_msg_len = 2;

  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            ack_msg, ack_msg_len,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_get_hub_ver(const hub_api_usart_msg_t *ptr_pkt,
                                  hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  (void)ptr_pkt;
  (void)ptr_ack_pkt;

  int year = 0;
  char month[10] = {'\0'};
  int day = 0;
  memset(ack_msg, 0, sizeof(ack_msg));

  sscanf(__DATE__, "%s %d %d",month, &day, &year);

  ack_msg[0] = ((STACK_VERSION>>16)&0xFF);
  ack_msg[1] = ((STACK_VERSION>>8)&0xFF);
  ack_msg[2] = (STACK_VERSION&0xFF);

  if(year > 2000){
      ack_msg[3] = year -2000;
  }
  ack_msg[4] = get_month_from_str(month);
  ack_msg[5] = day;
  ack_msg[6] = HUB_VER;

  ack_msg_len = 7;
  if(hub_log_enable){
      DS_app_log_error("v%d.%d.%d_build%02d%02d%02d%02d\r\n",ack_msg[0],
                   ack_msg[1],ack_msg[2],ack_msg[3],ack_msg[4],ack_msg[5],
                   ack_msg[6]);
  }
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            ack_msg, ack_msg_len,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_local_register(const hub_api_usart_msg_t *ptr_pkt,
                                      hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char sn[SN_LENGTH + 1] = {'\0'};
  unsigned char mac[MAC_ADDRESS_LENGTH] = {'\0'};
  unsigned char qr_key[16] = {'\0'};

  switch(ptr_pkt->data.rx_do_local_register_data.ctrl_data){
    case EXIT_LOCAL_MODE:
      break;
    case ENTER_LOCAL_MODE:
      break;
    default:
      err_code = PARAMETER_ERROR;
      break;
  }
  //if(hub_log_enable){
      APP_PRINTF("do local:%d\r\n",ptr_pkt->data.rx_do_local_register_data.ctrl_data);
  //}
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                                &err_code, 1,
                                ptr_ack_pkt);

  if(err_code == NO_ERROR){
      setThisParam(ENbyLocalRegister, (unsigned char *)&ptr_pkt->data.rx_do_local_register_data.ctrl_data);
      //if(ptr_pkt->data.rx_do_local_register_data.ctrl_data == ENTER_LOCAL_MODE){  //进入本地注册后，SN,MAC,QR_KEY都清空
          setThisParam(ENbyRegisterSN, (unsigned char *)sn);
          setThisParam(ENbyRegisterMAC, (unsigned char *)mac);
          setThisParam(ENbyRegisterQrKey, (unsigned char *)qr_key);
      //}
  }

  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return err_code;
}

HUB_API_WEAK int rx_do_mac_register(const hub_api_usart_msg_t *ptr_pkt,
                                   hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char local_register = ENTER_LOCAL_MODE;
  unsigned char sn[SN_LENGTH + 1] = {'\0'};
  unsigned char qr_key[16] = {'\0'};

  if(ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE != MAC_ADDRESS_LENGTH){
      err_code = PARAMETER_ERROR;
  }

  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  if(err_code == NO_ERROR){
      setThisParam(ENbyRegisterMAC, (unsigned char *)&ptr_pkt->data.rx_do_mac_register_data.mac);

      setThisParam(ENbyLocalRegister, (unsigned char *)&local_register); //进入注册模式，SN,QR_KEY都清空
      setThisParam(ENbyRegisterSN, (unsigned char *)sn);
      setThisParam(ENbyRegisterQrKey, (unsigned char *)qr_key);
  }

  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_qrcode_register(const hub_api_usart_msg_t *ptr_pkt,
                                       hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char local_register = ENTER_LOCAL_MODE;
  unsigned char sn[SN_LENGTH + 1] = {'\0'};

  if(ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE != (8+16)){
      err_code = PARAMETER_ERROR;
  }

  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                                  &err_code, 1,
                                  ptr_ack_pkt);

  if(err_code == NO_ERROR){
      setThisParam(ENbyRegisterMAC, (unsigned char *)&ptr_pkt->data.rx_do_qrcode_register_data.mac);
      setThisParam(ENbyRegisterQrKey, (unsigned char *)&ptr_pkt->data.rx_do_qrcode_register_data.qr_key);

      setThisParam(ENbyLocalRegister, (unsigned char *)&local_register); //进入注册模式，SN清空
      setThisParam(ENbyRegisterSN, (unsigned char *)sn);
  }

  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_sync_broadcast(const hub_api_usart_msg_t *ptr_pkt,
                                      hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char bcast_busy = 0;
  int len = 0;
  len = ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE;
  if(len <= 1){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy){
      err_code = DO_BUSY_ERROR;
      goto ack;
  }

  memset(ack_msg, 0, sizeof(ack_msg));
  ack_msg_len = 0;

  //去发同步广播
  (void)ptr_pkt->data.rx_do_sync_broadcast_data.brty;
  (void)ptr_pkt->data.rx_do_sync_broadcast_data.data;

  if(analysis_panel_bc_pkt(ptr_pkt->data.rx_do_sync_broadcast_data.data,
                           (len - 1),
                           &ack_msg[1],
                           &ack_msg_len)){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if(ack_msg_len){
      ack_msg[0] = ptr_pkt->data.rx_do_sync_broadcast_data.brty;
      ack_msg_len++;
      DS_hub_api_creat_rf_sync_broadcast_event(ack_msg,
                                               ack_msg_len);
  }
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_normal_broadcast(const hub_api_usart_msg_t *ptr_pkt,
                                        hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  int len = 0;
  len = ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE;
  if(len <= 1){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  memset(ack_msg, 0, sizeof(ack_msg));
  ack_msg_len = 0;

  //去发普通广播
  (void)ptr_pkt->data.rx_do_normal_broadcast_data.brty;
  (void)ptr_pkt->data.rx_do_normal_broadcast_data.data;

  if(analysis_panel_bc_pkt(ptr_pkt->data.rx_do_normal_broadcast_data.data,
                           (len - 1),
                           &ack_msg[1],
                           &ack_msg_len)){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if(ack_msg_len){
      ack_msg[0] = ptr_pkt->data.rx_do_normal_broadcast_data.brty;
      ack_msg_len++;
      DS_hub_api_creat_rf_normal_broadcast_event(ack_msg,
                                               ack_msg_len);
  }
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_point_to_point(const hub_api_usart_msg_t *ptr_pkt,
                                      hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  int len;

  unsigned char rfmid = get_rfmid_from_catno(
      ptr_pkt->data.rx_do_point_to_point_data.cat_type,
      ptr_pkt->data.rx_do_point_to_point_data.no);

  if(rfmid ==  0xff){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
#if(1)
  //判断该RFMID已注册
  if(!check_rfmid_is_registered(rfmid)){
      err_code = NOREGISTER_ERROR;
      goto ack;
  }
#endif
#if(0)
  //判断是长供电设备
  if(!check_this_is_power_device(rfmid)){
      err_code = POINT_TO_POINT_ERROR;
      goto ack;
  }
#endif

  memset(ack_msg, 0, sizeof(ack_msg));
  ack_msg_len = 0;

  //去发点对点通信
  (void)ptr_pkt->data.rx_do_point_to_point_data.cat_type;
  (void)ptr_pkt->data.rx_do_point_to_point_data.no;
  (void)ptr_pkt->data.rx_do_point_to_point_data.key_value;

  len = ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE -2;

  if(analysis_panel_p2p_pkt(ptr_pkt->data.rx_do_point_to_point_data.key_value,
                         len,
                         ack_msg,
                         &ack_msg_len,
                         rfmid)){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  if(ack_msg_len){
      DS_hub_api_creat_rf_point_to_point_event(rfmid,
                                               ack_msg,
                                               ack_msg_len);
  }

ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_delete_rfm(const hub_api_usart_msg_t *ptr_pkt,
                                 hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char rfmid = 0xff;
#if defined(HUB_AS_TEST_MACHINE) && defined (HUB_DEVICE)
  bool delete_busy = false;
  unsigned char updateme_bc[5] = {0x00};
  unsigned char del_led_ctrl[LEDCTRL_LENGTH] = {0, 0xDE, 0xCA, 1, 0, 0};
  unsigned char del_led_flag = 0;
  int time = 294912ul; //9S > (n+2)*2, 留了1S的余量

  rfmid = get_rfmid_from_catno(
      ptr_pkt->data.rx_do_delete_rfm_data.cat_type,
      ptr_pkt->data.rx_do_delete_rfm_data.no);

  APP_PRINTF("delete %02x\r\n",rfmid);
  if(rfmid ==  0xff){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  delete_busy = get_bc_delete();
  if(delete_busy){
      err_code = DO_BUSY_ERROR;
      goto ack;
  }
  updata_node_aseq(ASEQ_LED, rfmid);
  del_led_ctrl[0] = get_node_aseq(ASEQ_LED, rfmid);
  del_led_flag  = 1;
  setDeviceParam(rfmid, ENbyLedCtrl, (unsigned char *)del_led_ctrl);
  setDeviceParam(rfmid, ENbyLedCtrlFlag, (unsigned char *)&del_led_flag);
  updateme_bc[0] = 2;//bretry
  updateme_bc[1] = 0x08;
  updateme_bc[2] = 2;
  updateme_bc[3] = 0x00;//ctrl
  updateme_bc[4] = rfmid;
  DS_hub_api_creat_rf_sync_broadcast_event(updateme_bc, 5);
  set_delete_rfmid(rfmid);
  start_delete_rfm_timer(time, NULL);
#else

#ifndef CONFIG_NVM_VERSION
  unsigned char mac_addr[MAC_ADDRESS_LENGTH] = {0}; //删MAC地址
  unsigned char sn[SN_LENGTH] = {0}; //删SN
  unsigned char devicetype[3] = {0};
  unsigned char codeAB[KEY_MAX_LENGTH] = {0};
#endif
  unsigned char info[NODE_JOIN_INFO_LENGTH] = {0};  //删注册状态
  unsigned char option[OPTION_LENGTH] = {0};//删option
#ifndef CONFIG_NVM_VERSION
  unsigned char qrfh1 = 0;
  unsigned char qrfh2 = 0;
#endif
  unsigned char qrfr1 = 0;
  unsigned char qrfr2 = 0;
  unsigned char groupix = 0;
  unsigned char rollcode[ROLLING_CODE_LENGTH] = {0x00,0x00,0x00,0x00};
  unsigned char flag = 0;
  unsigned char led_ctrl[LEDCTRL_LENGTH] = {0};
  unsigned char operate_ctrl[OPERATECTRL_LENGTH] = {0};
  unsigned char keyvalue_get[GETKEYVALUE_LENGTH] = {0};
  int i = 0;
  unsigned char idx = 0;
  unsigned char bit = 0;
#ifdef CONFIG_NVM_VERSION
#ifdef HUB_DEVICE
  uint8_t nodeRegInfo[NODEREGINFO_MAX_LEN]={0};
  uint8_t qrfh12[NodeQrfH12Group_MAX_LEN]={0};
#endif
#endif

  if(ptr_pkt->data.rx_do_delete_rfm_data.cat_type == 0xff){
      //删除全部设备
      APP_PRINTF("delete all\r\n");
#ifndef CONFIG_NVM_VERSION
      setThisParam(ENbyNodeJoinInfo, (unsigned char *)info);
#endif
      for(i = 1; i < NODE_MAX_COUNT; i++){
#ifndef CONFIG_NVM_VERSION
          setNodeJoinCodeAB(codeAB, i);
          setNodeJoinMac(mac_addr, i);
          setDeviceParam(i, ENpbyNodeSNFirst, sn);
          setDeviceParam(i, ENpbyNodeOptionFirst, option);
          setDeviceParam(i, ENpbyNodeQrfH1First, &qrfh1);
          setDeviceParam(i, ENpbyNodeQrfH2First, &qrfh2);
          setDeviceParam(i, ENpbyNodeGroupIdxFirst, &groupix);
          setDeviceParam(i, HubRecvRollingCodeFirst, rollcode);
          setDeviceParam(i, ENpbyNodeDeviceTypeFirst, devicetype);
#endif
          clean_device_ram_qrfh_and_option(i); //nvm里的qrfh和option都被格式化了，这里删ram里的
          setDeviceParam(i, ENpbyNodeQrfR1First, &qrfr1);
          setDeviceParam(i, ENpbyNodeQrfR2First, &qrfr2);
          setDeviceParam(i, ENbyLedCtrlFlag, &flag);
          setDeviceParam(i, ENbyOperateCtrlFlag, &flag);
          setDeviceParam(i, ENbyKeyValueGetFlag, &flag);
          setDeviceParam(i, ENbyLedCtrl, led_ctrl);
          setDeviceParam(i, ENbyOperateCtrl, operate_ctrl);
          setDeviceParam(i, ENbyKeyValueGet, keyvalue_get);
          set_rfm_offline(i);
      }
#ifdef CONFIG_NVM_VERSION
#ifdef HUB_DEVICE
      device_hub_formatting();
#endif
#endif
  }else{
      rfmid = get_rfmid_from_catno(
          ptr_pkt->data.rx_do_delete_rfm_data.cat_type,
          ptr_pkt->data.rx_do_delete_rfm_data.no);

      APP_PRINTF("delete %02x\r\n",rfmid);
      if(rfmid ==  0xff){
          err_code = PARAMETER_ERROR;
          goto ack;
      }
      //删除rfmid设备
      getThisParam(ENbyNodeJoinInfo, (unsigned char *)info);

      idx = (rfmid - 1)/8;
      bit = (rfmid - 1)%8;
      HUB_API_CLEAN_BIT(info[idx], bit);
      setThisParam(ENbyNodeJoinInfo, (unsigned char *)info);
#ifdef CONFIG_NVM_VERSION
#ifdef HUB_DEVICE
      setNodeRegInfoPack(rfmid,nodeRegInfo);
      setNodeQrfH12Group(rfmid,qrfh12);
      clean_device_ram_qrfh(rfmid); //这里删ram里的qrfh
#endif
#else
      setNodeJoinMac(mac_addr, rfmid);
      setNodeJoinCodeAB(codeAB, rfmid);
      setDeviceParam(rfmid, ENpbyNodeSNFirst, sn);
      setDeviceParam(rfmid, ENpbyNodeQrfH1First, &qrfh1);
      setDeviceParam(rfmid, ENpbyNodeQrfH2First, &qrfh2);
      setDeviceParam(rfmid, ENpbyNodeDeviceTypeFirst, devicetype);
#endif
      setDeviceParam(rfmid, ENpbyNodeOptionFirst, option); //删ram和nvm里的option
      setDeviceParam(rfmid, ENpbyNodeQrfR1First, &qrfr1);
      setDeviceParam(rfmid, ENpbyNodeQrfR2First, &qrfr2);
      setDeviceParam(rfmid, ENpbyNodeGroupIdxFirst, &groupix);
      setDeviceParam(rfmid, HubRecvRollingCodeFirst, rollcode);
      setDeviceParam(rfmid, ENbyLedCtrlFlag, &flag);
      setDeviceParam(rfmid, ENbyOperateCtrlFlag, &flag);
      setDeviceParam(rfmid, ENbyKeyValueGetFlag, &flag);
      setDeviceParam(rfmid, ENbyLedCtrl, led_ctrl);
      setDeviceParam(rfmid, ENbyOperateCtrl, operate_ctrl);
      setDeviceParam(rfmid, ENbyKeyValueGet, keyvalue_get);
      set_rfm_offline(rfmid);
  }
  (void)ptr_pkt->data.rx_do_delete_rfm_data.cat_type;
  (void)ptr_pkt->data.rx_do_delete_rfm_data.no;
#ifdef HUB_DEVICE
  getAllNodeJoinMac();
#endif
#endif //#if defined(HUB_AS_TEST_MACHINE) && defined (HUB_DEVICE)
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}


HUB_API_WEAK void ota_enter_hook(void)
{

}

HUB_API_WEAK int rx_do_start_ota(const hub_api_usart_msg_t *ptr_pkt,
                                 hub_api_usart_msg_t *ptr_ack_pkt)
{
  (void)ptr_pkt;
  (void)ptr_ack_pkt;
  unsigned char err_code = NO_ERROR;
  unsigned char mode = 0;
  unsigned char id_max_num = 0;
  unsigned char id_buf[OTA_ID_BUF_MAX] = {0};
  unsigned char file_type = 0;
  unsigned char test[OTA_CONSULT_KEYVALUE_LENGTH] = {0};
  getThisParam(ENbyPanelSetOtaMode, (unsigned char *)&mode);
  if(mode == OTA_MODE_OTA_ING){
      //正在OTA
      if(ptr_pkt->data.data[0]){
          err_code = DO_BUSY_ERROR;
          goto ack;
      }else{
          setThisParam(ENbyPanelSetOtaMode, (unsigned char *)&ptr_pkt->data.data[0]);
          creat_ota_abort_event();
          goto ack;
      }
  }else{
      //没有进行OTA，panel继续do强制退出
      if(!ptr_pkt->data.data[0]){
          //err_code = DO_USELESS_ERROR;
          goto ack;
      }
  }
  if(ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE <= 11){ //mode[1]+Idnum[1]+IDBUF[N]+KEY[1]VALUE[8]
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  id_max_num = ptr_pkt->data.data[1];
  if(id_max_num == 0 || id_max_num > OTA_ID_BUF_MAX){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if((ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE) != (11 + id_max_num)){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if(ptr_pkt->data.data[2+id_max_num] != 0xfe){  //key
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  if(ptr_pkt->data.data[3+id_max_num] != 7){   //len
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  file_type = ptr_pkt->data.data[5+id_max_num];  //ftype
  if(file_type != 0x03 && file_type != 0x04 && file_type != 0x05){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  memcpy(id_buf, &ptr_pkt->data.data[2], id_max_num);
#if(FILE_TEST) //TODO测试多个设备OTA，正式固件删除
  id_max_num = 3;
  id_buf[0] = 0x01;
  id_buf[1] = 0x02;
  id_buf[2] = 0x03;
#endif
  setThisParam(ENbyPanelSetOtaMode, (unsigned char *)&ptr_pkt->data.data[0]);
  setThisParam(ENbyPanelSetOtaNum, (unsigned char *)&id_max_num);
  setThisParam(ENbyPanelSetOtaId, (unsigned char *)id_buf);

  setThisParam(ENbyOtaUpdatemeIDNum, (unsigned char *)&id_max_num);
  setThisParam(ENbyOtaUpdatemeID, (unsigned char *)id_buf);
#if(FILE_TEST) //TODO测试多个设备OTA，正式固件删除
  id_max_num = 1;
#endif
  setThisParam(ENbyTransFileType, (unsigned char *)&file_type);
  setThisParam(ENbyOtaConSultKeyValue, (unsigned char *)&ptr_pkt->data.data[2+id_max_num]);
  getThisParam(ENbyOtaConSultKeyValue, test);

  ota_enter_hook();
ack:
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_sn_register(const hub_api_usart_msg_t *ptr_pkt,
                                   hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char sn[SN_LENGTH + 1] = {'\0'};
  unsigned char len = 0;
  unsigned char local_register = ENTER_LOCAL_MODE;
  unsigned char mac[MAC_ADDRESS_LENGTH] = {'\0'};
  unsigned char qr_key[16] = {'\0'};

  len = (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE);
  if(len > SN_LENGTH){
      err_code = PARAMETER_ERROR;
  }

  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  if(err_code == NO_ERROR){
      for(int i = 0; i < len; i++){
          sn[i] = ptr_pkt->data.rx_do_sn_register_data.sn[i];
      }
      //if(hub_log_enable){
          APP_PRINTF("do sn:");
          for(int i = 0; i < SN_LENGTH; i++){
              APP_PRINTF("%c",sn[i]);
          }
          APP_PRINTF("\r\n");
      //}
      setThisParam(ENbyRegisterSN, (unsigned char *)sn);

      setThisParam(ENbyLocalRegister, (unsigned char *)&local_register); //进入本地注册，清MAC QR_KEY
      setThisParam(ENbyRegisterMAC, (unsigned char *)mac);
      setThisParam(ENbyRegisterQrKey, (unsigned char *)qr_key);
  }
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_file_transport(const hub_api_usart_msg_t *ptr_pkt,
                                   hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char len = 0;
  unsigned char file_len = 0;
  unsigned char mode = 0;
  unsigned char file_data[224] = {0};

  //note:rx_do_file_transport_data是可变长的，实际使用时，check_code并不一定在data[224]之后
  getThisParam(ENbyPanelSetOtaMode,&mode);
  if(mode == OTA_MODE_NO_OTA){
      err_code = DO_USELESS_ERROR;
      goto ack;
  }
  //判断当前的文件缓存队列有没有满
#ifdef HUB_DEVICE
  if(check_ota_suspend_production()){
      err_code = DO_USELESS_ERROR;
      goto ack;
  }
#endif
  len = (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE);
  if(len < 6){
      err_code = PARAMETER_ERROR;
      goto ack;
  }
  file_len = len - 6;
  if(file_len > 224){
      err_code = PARAMETER_ERROR;
      goto ack;
  }

  if(!chcek_block_match_by_pageid((unsigned char *)ptr_pkt->data.rx_do_file_transport_data.page)){
      if(hub_log_enable){
          APP_PRINTF("block_id match error, pageId[%d]\r\n",
                 ((ptr_pkt->data.rx_do_file_transport_data.page[0] << 8)+ptr_pkt->data.rx_do_file_transport_data.page[1]));
      }
      err_code = DO_USELESS_ERROR;
      goto ack;
  }

  if(chcek_file_is_exist_by_pageid((unsigned char *)ptr_pkt->data.rx_do_file_transport_data.page)){
      if(hub_log_enable){
          APP_PRINTF("page exist error, pageId[%d]\r\n",
                 ((ptr_pkt->data.rx_do_file_transport_data.page[0] << 8)+ptr_pkt->data.rx_do_file_transport_data.page[1]));
      }
      err_code = NO_ERROR;//err_code = DO_USELESS_ERROR; 收到相同的文件不再报错，避免不同步
      goto ack;
  }

  memcpy(file_data, &ptr_pkt->data.rx_do_file_transport_data.data, file_len);
  if(!check_file_crc32_is_sample(file_data, file_len,
                                 (unsigned char *)&ptr_pkt->data.rx_do_file_transport_data.data[file_len + 0], 4)){
      if(hub_log_enable){
          APP_PRINTF("file crc error, pageId[%d]\r\n",
                 ((ptr_pkt->data.rx_do_file_transport_data.page[0] << 8)+ptr_pkt->data.rx_do_file_transport_data.page[1]));
      }
      err_code = FILE_CRC32_ERROR;
      goto ack;

  }
  filepayload_cache_to_file_link((unsigned char *)ptr_pkt->data.rx_do_file_transport_data.page,
                                 (file_len + 6));

ack:
    pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                              &err_code, 1,
                              ptr_ack_pkt);
    DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
    return 0;
}

HUB_API_WEAK int rx_do_choose_ant(const hub_api_usart_msg_t *ptr_pkt,
                                  hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char ant_mode = 0;
  if( (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE) != 2){
      err_code = PARAMETER_ERROR;
  }
  if(err_code == NO_ERROR){
      (void)ptr_pkt->data.rx_do_choose_ant_data.ant_mode;
      (void)ptr_pkt->data.rx_do_choose_ant_data.ant_idx;
      ant_mode = (ptr_pkt->data.rx_do_choose_ant_data.ant_mode) ? 1 : 0; //1外部 0内部
      bsp_rf_antenna_select(ant_mode);
      //TODO 内置天线选择0还是1 不确定是否需要配置
  }
  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                            &err_code, 1,
                            ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_do_stop_sync_broadcast(const hub_api_usart_msg_t *ptr_pkt,
                                           hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  unsigned char bcast_busy = 0;

  stop_twoway_broadcast_retry_timer();
  setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);

  pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                              &err_code, 1,
                              ptr_ack_pkt);
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}


HUB_API_WEAK int rx_do_test(const hub_api_usart_msg_t *ptr_pkt,
                            hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char err_code = NO_ERROR;
  //unsigned char freq = 0;
  int channe = 0;
  RAIL_TxPower_t tx_power = 0;
  unsigned char enable = 0;
  RAIL_StreamMode_t mode = 0;
  unsigned char ant_idx = 0;
  RAIL_TxOptions_t option = 0;
  int ctune = 0;
  unsigned char lfxo_ctune = 0;
  CMU_LFXOInit_TypeDef lfxoInit = CMU_LFXOINIT_DEFAULT;

  memset(ack_msg, 0, sizeof(ack_msg));
  ack_msg_len = 0;

  switch(ptr_pkt->data.rx_do_test_data.ctrl){
    case TEST_TONE_CTRL:
      if(ptr_pkt->data.rx_do_test_data.data_len != 8){
          err_code = PARAMETER_ERROR;
          goto ack;
      }
      (void)ptr_pkt->data.rx_do_test_data.data[0];  //freq
      channe = (ptr_pkt->data.rx_do_test_data.data[1] << 8)+
          ptr_pkt->data.rx_do_test_data.data[2];
      tx_power = (ptr_pkt->data.rx_do_test_data.data[3] << 8)+
          ptr_pkt->data.rx_do_test_data.data[4];
      enable = ptr_pkt->data.rx_do_test_data.data[5];
      mode = ptr_pkt->data.rx_do_test_data.data[6];
      ant_idx = ptr_pkt->data.rx_do_test_data.data[7];
      if(enable){
          bsp_set_rf_idle(RAIL_IDLE_ABORT, true);

          bsp_rf_set_tx_power_bdm(tx_power);
          tx_power = bsp_rf_get_tx_power_bdm();
          setThisParam(RfTxPower, &tx_power);

          option = (ant_idx) ? RAIL_TX_OPTION_ANTENNA1 : RAIL_TX_OPTION_ANTENNA0;

          bsp_rf_start_tx_stream_alt(channe, mode, option);
      }else{
          bsp_rf_stop_tx_stream();
      }
      break;
    case SET_CTUNE_CTRL:
      if(ptr_pkt->data.rx_do_test_data.data_len != 4){
          err_code = PARAMETER_ERROR;
          goto ack;
      }
      ctune = (ptr_pkt->data.rx_do_test_data.data[0] << 24) +
              (ptr_pkt->data.rx_do_test_data.data[1] << 16) +
              (ptr_pkt->data.rx_do_test_data.data[2] << 8) +
              (ptr_pkt->data.rx_do_test_data.data[3]);
      bsp_set_rf_idle(RAIL_IDLE_ABORT, true);

      bsp_rf_set_ctune(ctune);
      ctune = bsp_rf_get_ctune();
      setThisParam(RfCtune, &ctune);
      break;
    case SET_LFXO_CTUNE_CTRL:
      if(ptr_pkt->data.rx_do_test_data.data_len != 1){
          err_code = PARAMETER_ERROR;
          goto ack;
      }

      lfxo_ctune = ptr_pkt->data.rx_do_test_data.data[0];

      lfxoInit.mode = cmuLfxoOscMode_Crystal;
      lfxoInit.capTune = lfxo_ctune;
      lfxoInit.timeout = cmuLfxoStartupDelay_4KCycles;

      CMU_LFXOInit(&lfxoInit);
      CMU_LFXOPrecisionSet(100);

      setThisParam(lfxoCtune, &lfxo_ctune);
      break;
    case LFXO_CLK_CTRL:
      if(ptr_pkt->data.rx_do_test_data.data_len != 1){
          err_code = PARAMETER_ERROR;
          goto ack;
      }
      GPIO_DbgSWDIOEnable(false);
      GPIO_DbgSWDClkEnable(false);
      if(ptr_pkt->data.rx_do_test_data.data[0]){
          CMU_ClkOutPinConfig(2, cmuSelect_LFXO, 1, gpioPortA, 1);
      }else{
          CMU_ClkOutPinConfig(2, cmuSelect_Disabled, 1, gpioPortA, 1);
      }
      break;
    case GET_PANID_CTRL:
      getThisParam(ENpbyPanId, &ack_msg[1]);
      ack_msg[0] = NO_ERROR;
      ack_msg_len = 1 + PANID_LENGTH;
      break;
    case SET_PANID_CTRL:
      if(ptr_pkt->data.rx_do_test_data.data_len != PANID_LENGTH){
          err_code = PARAMETER_ERROR;
          goto ack;
      }
      if(getNodeJoinCount()){
          err_code = DO_USELESS_ERROR;
          goto ack;
      }
      setThisParam(ENpbyPanId, (unsigned char *)ptr_pkt->data.rx_do_test_data.data);
#if(1) //TODO 主HUB SystemID，PanId保持一致；
      setThisParam(ENpbySystemID, (unsigned char *)ptr_pkt->data.rx_do_test_data.data);
#else //中继设备没有主HUB的逻辑

#endif
      break;
    default:
      err_code = PARAMETER_ERROR;
      break;
  }

ack:
  if(ack_msg_len){
      pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                                ack_msg, ack_msg_len,
                                ptr_ack_pkt);
  }else{
      pack_passive_usart_packet(ptr_pkt->fcode, err_code,
                                &err_code, 1,
                                ptr_ack_pkt);
  }
  DS_hub_api_creat_passive_usart_ack(ptr_ack_pkt);
  return 0;
}

HUB_API_WEAK int rx_event_hub_event(const hub_api_usart_msg_t *ptr_pkt,
                                    hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char tns = 0;
  unsigned char flag = 0;

  (void)ptr_pkt;
  (void)ptr_ack_pkt;

  setThisParam(ENbyEvtA0TNS, (unsigned char *)&tns);
  setThisParam(ENbyEvtA0AckFlag, (unsigned char *)&flag);

  return 0;
}

HUB_API_WEAK int rx_event_rfm_event(const hub_api_usart_msg_t *ptr_pkt,
                                    hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char tns = 0;
  unsigned char flag = 0;

  (void)ptr_pkt;
  (void)ptr_ack_pkt;

  setThisParam(ENbyEvtA1TNS, (unsigned char *)&tns);
  setThisParam(ENbyEvtA1AckFlag, (unsigned char *)&flag);

  return 0;
}

HUB_API_WEAK int rx_event_file_transfer(const hub_api_usart_msg_t *ptr_pkt,
                                        hub_api_usart_msg_t *ptr_ack_pkt)
{
  unsigned char tns = 0;
  unsigned char flag = 0;

  (void)ptr_pkt;
  (void)ptr_ack_pkt;

  setThisParam(ENbyEvtA2TNS, (unsigned char *)&tns);
  setThisParam(ENbyEvtA2AckFlag, (unsigned char *)&flag);

  return 0;
}

HUB_API_WEAK int rx_event_rfm_debug_event(const hub_api_usart_msg_t *ptr_pkt,
                                    hub_api_usart_msg_t *ptr_ack_pkt)
{
  (void)ptr_pkt;
  (void)ptr_ack_pkt;

  return 0;
}

const hub_api_usart_tx_entry_t ds_hub_api_tx_fcode_table[] ={
    {P_TO_H_SET_INIT, tx_set_init},
    {P_TO_H_SET_RFM_QRFH, tx_set_rfm_qrfh},
    {P_TO_H_SET_RFM_QRFH_BATCH, tx_set_rfm_qrfh_batch},
    {P_TO_H_SET_RFM_STATUS_MODEL, tx_set_rfm_status_model},
    {P_TO_H_SET_RFM_OPERATE_MODEL, tx_set_rfm_operate_model},
    {P_TO_H_SET_RFM_SYNC_OPTION_BATCH, tx_set_rfm_sync_option_batch},
    {P_TO_H_SET_RFM_SYNC_QRFH_BATCH, tx_set_rfm_sync_qrfh_batch},
    {P_TO_H_SET_HUB_RESET, tx_set_hub_reset},

    {P_TO_H_GET_REGISTERED_RFM_INFO, tx_get_registered_rfm_info},
    {P_TO_H_GET_SPECIFIC_RFM_INFO, tx_get_specific_rfm_info},
    {P_TO_H_GET_HUB_PHYSICAL, tx_get_hub_physical},
    {P_TO_H_GET_HUB_RSSI, tx_get_hub_rssi},
    {P_TO_H_GET_HUB_VER, tx_get_hub_ver},

    {P_TO_H_DO_LOCAL_REGISTER, tx_do_local_register},
    {P_TO_H_DO_MAC_REGISTER, tx_do_mac_register},
    {P_TO_H_DO_QRCODE_REGISTER, tx_do_qrcode_register},
    {P_TO_H_DO_SYNC_BROADCAST, tx_do_sync_broadcast},
    {P_TO_H_DO_NORMAL_BROADCAST, tx_do_normal_broadcast},
    {P_TO_H_DO_POINT_TO_POINT, tx_do_point_to_point},
    {P_TO_H_DO_DELETE_RFM, tx_do_delete_rfm},
    {P_TO_H_DO_START_OTA, tx_do_start_ota},
    {P_TO_H_DO_SN_REGISTER, tx_do_sn_register},
    {P_TO_H_DO_FILE_TRANSPORT,tx_do_file_transport},
    {P_TO_H_DO_CHOOSE_ANT, tx_do_choose_ant},
    {P_TO_H_DO_STOP_SYNC_BROADCAST, tx_do_stop_sync_broadcast},
    {P_TO_H_DO_TEST, tx_do_test},

    {H_TO_P_EVENT_HUB_EVENT, tx_event_hub_event},
    {H_TO_P_EVENT_RFM_EVENT, tx_event_rfm_event},
    {H_TO_P_EVENT_FILE_TRANSFER, tx_event_file_event},
    {H_TO_P_EVENT_RFM_DEBUG_EVENT, tx_event_rfm_debug_event},
};

#define usart_tx_cmd_num (sizeof(ds_hub_api_tx_fcode_table)/sizeof(ds_hub_api_tx_fcode_table[0]))

static unsigned char active_packet_add_statu_byte(void)
{
  unsigned char statu = 0;
  unsigned char bcast_busy = 0;
  unsigned char cfg_req = 0;

  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  getThisParam(ENbyCfgReq, (unsigned char *)&cfg_req);

  if(bcast_busy){
      HUB_API_SET_BIT(statu, 1);
  }
  if(cfg_req){
      HUB_API_SET_BIT(statu, 0);
  }
  return statu;
}

int DS_hub_api_push_usart_tx_event(void *msg, int len)
{
  int iret = DS_app_hub_api_usart_tx_event_link_push(msg, len);
  if(iret){
  }
  return iret;
}

int DS_hub_api_creat_usart_tx_event(const hub_api_usart_msg_t *ptr_pkt)
{
  unsigned char msg[HUB_API_USART_MSG_MAX_LEN] = {0};
  int len = 0;
  int i = 0;

  msg[len++] = ptr_pkt->stx;
  msg[len++] = ptr_pkt->seq;
  msg[len++] = ptr_pkt->len;
  msg[len++] = ptr_pkt->statu;
  msg[len++] = ptr_pkt->fcode;
  for(i = 0; i < (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE); i++){
      msg[len++] = ptr_pkt->data.data[i];
  }
  msg[len++] = ptr_pkt->crc[0];
  msg[len++] = ptr_pkt->crc[1];
  msg[len++] = ptr_pkt->etx;

  return DS_hub_api_push_usart_tx_event((unsigned char *)msg, len);
}

int DS_hub_api_push_usart_retry_tx_event(void *msg, int len)
{
  int iret = DS_app_hub_api_usart_tx_event_link_re_push(msg, len);
  if(iret){
  }
  return iret;
}

int DS_hub_api_creat_usart_retransmission(const hub_api_usart_msg_t *ptr_pkt)
{
  unsigned char msg[HUB_API_USART_MSG_MAX_LEN] = {0};
  int len = 0;
  int i = 0;

  msg[len++] = ptr_pkt->stx;
  msg[len++] = ptr_pkt->seq;
  msg[len++] = ptr_pkt->len;
  msg[len++] = ptr_pkt->statu;
  msg[len++] = ptr_pkt->fcode;
  for(i = 0; i < (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE); i++){
      msg[len++] = ptr_pkt->data.data[i];
  }
  msg[len++] = ptr_pkt->crc[0];
  msg[len++] = ptr_pkt->crc[1];
  msg[len++] = ptr_pkt->etx;

  return DS_hub_api_push_usart_retry_tx_event((unsigned char *)msg, len);
}


void DS_hub_api_creat_passive_usart_ack(const hub_api_usart_msg_t *ptr_pkt)
{
  DS_hub_api_creat_usart_tx_event(ptr_pkt);
}

void DS_hub_api_P2P_do_finish(unsigned char rfmid,
                           unsigned char result,
                           unsigned char *keyvalue, int keyvalue_len)
{
  unsigned char msg[HUB_API_USART_MSG_DATA_MAX_LEN - 1] = {0};
  int msg_len = 0;
  unsigned char cat_type = 0;
  unsigned char no = 0;
  unsigned char key = 0;

  unsigned char led_ctrl[LEDCTRL_LENGTH] = {0x00};
  unsigned char value = 0;
  unsigned char operate_ctrl[OPERATECTRL_LENGTH] = {0};
  unsigned char option_ctrl[OPTION_LENGTH] = {0};
  unsigned char ioput[2] = {0};
  unsigned char temp_humi[4] = {0};
  unsigned char volt_power[5] = {0};
  unsigned char runtime_energy[8] = {0};
  int i,j;
  uint8_t devicetype[3] = {0};

  if(!keyvalue || !keyvalue_len || keyvalue_len > (HUB_API_USART_MSG_DATA_MAX_LEN - 7) ){
      return;
  }
  i = j = 0;

  cat_type = get_cat_from_rfmid(rfmid);
  no = get_no_from_cat_rfmid(cat_type, rfmid);
  getDeviceParam(rfmid, ENpbyNodeDeviceTypeFirst, devicetype);

  msg[msg_len++] = cat_type;
  msg[msg_len++] = no;
  msg[msg_len++] = devicetype[0];
  msg[msg_len++] = devicetype[1];
  msg[msg_len++] = devicetype[2];
  msg[msg_len++] = result;

  while((i + 1) < keyvalue_len){
      key = keyvalue[i];
      if(key == COMLED_CTRL_KEY){
          for(j = 0; (j < LEDCTRL_LENGTH) && ((i+1+j) < keyvalue_len); j++){  //LEDCTRL_LENGTH，含Aseq
              led_ctrl[j] = keyvalue[i+1+j];
          }
          if(j == LEDCTRL_LENGTH){
              msg[msg_len++] = COMLED_CTRL_KEY;
              memcpy(&msg[msg_len], &led_ctrl[1], (LEDCTRL_LENGTH - 1));
              msg_len += (LEDCTRL_LENGTH - 1);
              msg[msg_len++] = led_ctrl[0];
          }else{
              return;
          }
          i = i + LEDCTRL_LENGTH + 1;
      }else if(key == KEYVALUE_GET_KEY){
          for(j = 0; (j < 1) && ((i+1+j) < keyvalue_len); j++){
              value = keyvalue[i+1+j];
          }
          if(j == 1){
              msg[msg_len++] = KEYVALUE_GET_KEY;
              msg[msg_len++] = value;
              msg[msg_len++] = 0;   //无aseq
          }else{
              return;
          }
          i = i + 2;
      }else if(key == OPERATE_CTRL_KEY){
          for(j = 0; (j < OPERATECTRL_LENGTH) && ((i+1+j) < keyvalue_len); j++){ //OPERATECTRL_LENGTH，含Aseq
              operate_ctrl[j] = keyvalue[i+1+j];
          }
          if(j == OPERATECTRL_LENGTH){
              msg[msg_len++] = OPERATE_CTRL_KEY;
              memcpy(&msg[msg_len], &operate_ctrl[1], (OPERATECTRL_LENGTH - 1));
              msg_len += (OPERATECTRL_LENGTH - 1);
              msg[msg_len++] = operate_ctrl[0];
          }else{
              return;
          }
          i = i + OPERATECTRL_LENGTH + 1;
      }else if(key == OPTION_KEY){
          for(j = 0; (j < OPTION_LENGTH) && ((i+1+j) < keyvalue_len); j++){
              option_ctrl[j] = keyvalue[i+1+j];
          }
          if(j == OPTION_LENGTH){
              msg[msg_len++] = OPTION_KEY;
              memcpy(&msg[msg_len], &option_ctrl[0], OPTION_LENGTH);
              msg_len += OPTION_LENGTH;
              msg[msg_len++] = 0; //无aseq
          }else{
              return;
          }
          i = i + OPTION_LENGTH + 1;
      }else if(key == IOPUT_KEY){
          for(j = 0; (j < 2) && ((i+1+j) < keyvalue_len); j++){
              ioput[j] = keyvalue[i+1+j];
          }
          if(j == 2){
              msg[msg_len++] = IOPUT_KEY;
              memcpy(&msg[msg_len], &ioput[0], 2);
              msg_len += 2;
              msg[msg_len++] = 0; //无aseq
          }else{
              return;
          }
          i = i + 2 + 1;
      }else if(key == TEMPHUMI_KEY){
          for(j = 0; (j < 4) && ((i+1+j) < keyvalue_len); j++){
              temp_humi[j] = keyvalue[i+1+j];
          }
          if(j == 4){
              msg[msg_len++] = TEMPHUMI_KEY;
              memcpy(&msg[msg_len], &temp_humi[0], 4);
              msg_len += 4;
              msg[msg_len++] = 0; //无aseq
          }else{
              return;
          }
          i = i + 4 + 1;
      }else if(key == VOLTCPOWER_KEY){
          for(j = 0; (j < 5) && ((i+1+j) < keyvalue_len); j++){
              volt_power[j] = keyvalue[i+1+j];
          }
          if(j == 5){
              msg[msg_len++] = VOLTCPOWER_KEY;
              memcpy(&msg[msg_len], &volt_power[0], 5);
              msg_len += 5;
              msg[msg_len++] = 0; //无aseq
          }else{
              return;
          }
          i = i + 5 + 1;
      }else if(key == RUNTIMEENERGY_KEY){
          for(j = 0; (j < 8) && ((i+1+j) < keyvalue_len); j++){
              runtime_energy[j] = keyvalue[i+1+j];
          }
          if(j == 8){
              msg[msg_len++] = RUNTIMEENERGY_KEY;
              memcpy(&msg[msg_len], &runtime_energy[0], 8);
              msg_len += 8;
              msg[msg_len++] = 0; //无aseq
          }else{
              return;
          }
          i = i + 8 + 1;
      }else{
          return;
      }
  }

  DS_hub_api_creat_hub_event(P2P_DO_FINISH, msg, msg_len);
}

void DS_hub_api_creat_hub_event(HUB_API_HUB_EVT_TYPE_E evt_type,
                                unsigned char *data, int len)
{
  hub_api_usart_msg_t pkt = {0};
  unsigned short crc_value = 0;
  unsigned char bcast_busy = 0;
  int i = 0;

  switch(evt_type){
    case NEED_INIT:
    case BCAST_FINISH:
    case P2P_DO_FINISH:
    case NEED_SYNC_PRM:
    case JAMMING_EVT:
      break;
    default:
      return;
      break;
  }

  if(evt_type == BCAST_FINISH){
      setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
#if defined(HUB_AS_TEST_MACHINE) && defined (HUB_DEVICE)
      if(get_bc_delete()){ //产测时删子设备的广播完成事件，不发给linux
          return;
      }
#endif
  }

  if(len > (HUB_API_USART_MSG_DATA_MAX_LEN - 1)){
      if(hub_log_enable){
          DS_app_log_error("creat hub event fail\n");
      }
      return;
  }
  if(len){
      if(!data){
          return;
      }
  }else{
      //没有参数，data可以为NULL
  }

  pkt.stx = 0x02;
  pkt.seq = packet_add_seq_byte();
  pkt.len = 0;
  pkt.statu = active_packet_add_statu_byte();
  pkt.fcode = H_TO_P_EVENT_HUB_EVENT;
  pkt.data.tx_event_hub_event_data.event_type = evt_type;
  for(i = 0; i < len; i++){
      pkt.data.tx_event_hub_event_data.data[i] = data[i];
  }
  pkt.len = HUB_API_USART_MSG_LEN_MIN_VALUE + 1 + len;
  crc_value = B_L_SWAP_16(get_msg_crc16(&pkt.len, pkt.len + 1 -2));
  pkt.crc[0] = (crc_value >> 8)&0xff;
  pkt.crc[1] = (crc_value)&0xff;
  pkt.etx = 0x03;

  DS_hub_api_creat_usart_tx_event(&pkt);
}

void DS_hub_api_creat_rfm_event(unsigned char rfmid,
                                unsigned char rollingcode[4],
                                unsigned char rssi,
                                unsigned char dbginfo[2],
                                unsigned char cmd,
                                unsigned char *payload,
                                unsigned char payload_len)
{
  hub_api_usart_msg_t pkt = {0};
  unsigned short crc_value = 0;
  unsigned char cat_type = 0;
  unsigned char no = 0;
  unsigned char type[3] = {0};
  unsigned char msg[HUB_API_USART_MSG_DATA_MAX_LEN - 13] = {0};
  unsigned char msg_len = 0;
  unsigned char payload_idx = 0;
  int result_msg_len = 0;
  unsigned char register_ctrl = 0;

  if(!rollingcode || !dbginfo || !payload || !payload_len){
      return;
  }

  //if(payload_len > (HUB_API_USART_MSG_DATA_MAX_LEN - 13)){ //tx_event_rfm_event_data.payload[]
  if(payload_len > sizeof(pkt.data.tx_event_rfm_event_data.payload)){
      if(hub_log_enable){
          DS_app_log_error("creat rfm event fail\n");
      }
      return;
  }
  set_rfm_offline_countdown(rfmid);

  pkt.stx = 0x02;
  pkt.seq = packet_add_seq_byte();
  pkt.len = 0;
  pkt.statu = active_packet_add_statu_byte();
  pkt.fcode = H_TO_P_EVENT_RFM_EVENT;    //可能会被替换成 H_TO_P_EVENT_RFM_DEBUG_EVENT

  cat_type = get_cat_from_rfmid(rfmid);
  no = get_no_from_cat_rfmid(cat_type, rfmid);

  pkt.data.tx_event_rfm_event_data.cat_type = cat_type;
  pkt.data.tx_event_rfm_event_data.no = no;

  getDeviceParam(rfmid, ENpbyNodeDeviceTypeFirst, type);

  pkt.data.tx_event_rfm_event_data.device_type = type[0];
  pkt.data.tx_event_rfm_event_data.model_type = type[1];
  pkt.data.tx_event_rfm_event_data.hard_type = type[2];

  memcpy((char *)&pkt.data.tx_event_rfm_event_data.rolling_code,
         rollingcode, 4);
  pkt.data.tx_event_rfm_event_data.rssi = rssi;
  memcpy((char *)&pkt.data.tx_event_rfm_event_data.debug_info,
         dbginfo, 2);
  pkt.data.tx_event_rfm_event_data.cmd = cmd;
#if(1)
  if(cmd == 0x03){
      memcpy((char *)&pkt.data.tx_event_rfm_event_data.payload,
                   payload, payload_len);
      pkt.len = HUB_API_USART_MSG_LEN_MIN_VALUE+13+payload_len;
      getThisParam(ENbyLocalRegister, &register_ctrl);
      if(register_ctrl == 0){ //不在注册模式
          pkt.fcode = H_TO_P_EVENT_RFM_DEBUG_EVENT;
      }else{
          if(memcmp_sn(&pkt.data.tx_event_rfm_event_data.payload[27]) == false){ //SN不匹配
              pkt.fcode = H_TO_P_EVENT_RFM_DEBUG_EVENT;
          }
      }
      if(pkt.fcode == H_TO_P_EVENT_RFM_EVENT){
          if(check_rfm_is_join_pub_lock(rfmid)){
              if(hub_log_enable){
                  DS_app_log_error("rfmid %02x has pubbed\r\n",rfmid);
              }
              return;
          }else{
              lock_rfm_join_pub(rfmid);
          }
      }
      creat_rfm_add_cjson(rfmid,
                          pkt.data.tx_event_rfm_event_data.device_type,
                          pkt.data.tx_event_rfm_event_data.payload[5],
                          pkt.data.tx_event_rfm_event_data.payload[4],
                          pkt.data.tx_event_rfm_event_data.payload[6],
                          &pkt.data.tx_event_rfm_event_data.payload[21]);
  }else if(cmd == 0x04 || cmd == 0x05){
      if(payload_len < 10){
          return;
      }
      msg_len = 0;
      payload_idx = 0;
      memcpy((char *)(msg + msg_len), (payload + payload_idx), 10);  //mac[2]+seq[1]+retry[1]+v[1]+rssi[1]+temp[1]+r1[1]+r2[1]+res[1]
      msg_len = 10;
      payload_idx = 10;

      if(analysis_rfm_evt_payload_keyvalue((payload + payload_idx), (payload_len - 10),
                                           (msg + msg_len), &result_msg_len, rfmid)){
          return;
      }
      creat_rfm_report_cjson(rfmid,
                             pkt.data.tx_event_rfm_event_data.device_type,
                             msg[5],
                             msg[4],
                             msg[6]);

      msg_len += result_msg_len;

      memcpy((char *)&pkt.data.tx_event_rfm_event_data.payload,
         msg, msg_len);
      pkt.len = HUB_API_USART_MSG_LEN_MIN_VALUE+13+msg_len;

  }else{
#if defined(HUB_AS_TEST_MACHINE) && defined (HUB_DEVICE)
      if(payload_len < 10){
          return;
      }
      msg_len = 0;
      payload_idx = 0;
      memcpy((char *)(msg + msg_len), (payload + payload_idx), 10);  //mac[2]+seq[1]+retry[1]+v[1]+rssi[1]+temp[1]+r1[1]+r2[1]+res[1]
      msg_len = 10;
      payload_idx = 10;

      if(analysis_rfm_evt_payload_keyvalue((payload + payload_idx), (payload_len - 10),
                                           (msg + msg_len), &result_msg_len, rfmid)){
          return;
      }
      creat_rfm_report_cjson(rfmid,
                             pkt.data.tx_event_rfm_event_data.device_type,
                             msg[5],
                             msg[4],
                             msg[6]);

      msg_len += result_msg_len;

      memcpy((char *)&pkt.data.tx_event_rfm_event_data.payload,
             msg, msg_len);
      pkt.len = HUB_API_USART_MSG_LEN_MIN_VALUE+13+msg_len;
#else
      memcpy((char *)&pkt.data.tx_event_rfm_event_data.payload,
             payload, payload_len);
      pkt.len = HUB_API_USART_MSG_LEN_MIN_VALUE+13+payload_len;
#endif
  }
#else
  memcpy((char *)&pkt.data.tx_event_rfm_event_data.payload,
         payload, payload_len);
  pkt.len = HUB_API_USART_MSG_LEN_MIN_VALUE+13+payload_len;
#endif

  crc_value = B_L_SWAP_16(get_msg_crc16(&pkt.len, pkt.len + 1 -2));
  pkt.crc[0] = (crc_value >> 8)&0xff;
  pkt.crc[1] = (crc_value)&0xff;
  pkt.etx = 0x03;

  DS_hub_api_creat_usart_tx_event(&pkt);
}

void DS_hub_api_creat_file_event(HUB_API_FILE_EVT_TYPE_E evt_type,
                                unsigned char *data, int len)
{
  hub_api_usart_msg_t pkt = {0};
  unsigned short crc_value = 0;
  int i = 0;

  if(evt_type != NEED_FILE_TRANSPORT && evt_type != FILE_FINISH_TRANSPORT){
      return;
  }
  if(len > (HUB_API_USART_MSG_DATA_MAX_LEN - 1)){
      if(hub_log_enable){
          DS_app_log_error("creat file event fail\n");
      }
      return;
  }
  if(!data){
      return;
  }

  pkt.stx = 0x02;
  pkt.seq = packet_add_seq_byte();
  pkt.len = 0;
  pkt.statu = active_packet_add_statu_byte();
  pkt.fcode = H_TO_P_EVENT_FILE_TRANSFER;
  pkt.data.tx_event_file_event_data.event_type = evt_type;
  for(i = 0; i < len; i++){
      pkt.data.tx_event_file_event_data.data[i] = data[i];
  }
  pkt.len = HUB_API_USART_MSG_LEN_MIN_VALUE + 1 + len;
  crc_value = B_L_SWAP_16(get_msg_crc16(&pkt.len, pkt.len + 1 -2));
  pkt.crc[0] = (crc_value >> 8)&0xff;
  pkt.crc[1] = (crc_value)&0xff;
  pkt.etx = 0x03;

  DS_hub_api_creat_usart_tx_event(&pkt);
}

int DS_hub_api_pop_usart_tx_event(void *msg, int *ptr_len)
{
  int iret = DS_app_hub_api_usart_tx_event_link_pop(msg, ptr_len);
  if(iret){
  }
  return iret;
}

int DS_hub_api_get_usart_tx_event(hub_api_tx_evt_t *ptr_pkt)
{
  unsigned char msg[HUB_API_USART_MSG_MAX_LEN] = {0};
  int len = 0;
  int i = 0;
  int idx = 0;

  if(DS_hub_api_pop_usart_tx_event((unsigned char *)msg, &len)){
      return 1;
  }
  if(!len  || len < 8){
      return 1;
  }
  if((msg[2] + 4) != len){
      return 1;
  }
  ptr_pkt->channel = EVT_USART_TX;

  ptr_pkt->msg.usart_msg.stx = msg[idx++];
  ptr_pkt->msg.usart_msg.seq = msg[idx++];
  ptr_pkt->msg.usart_msg.len = msg[idx++];
  ptr_pkt->msg.usart_msg.statu = msg[idx++];
  ptr_pkt->msg.usart_msg.fcode = msg[idx++];

  for(i = 0; i < (ptr_pkt->msg.usart_msg.len - HUB_API_USART_MSG_LEN_MIN_VALUE); i++){
      ptr_pkt->msg.usart_msg.data.data[i] = msg[idx++];
  }
  ptr_pkt->msg.usart_msg.crc[0] = msg[idx++];
  ptr_pkt->msg.usart_msg.crc[1] = msg[idx++];
  ptr_pkt->msg.usart_msg.etx = msg[idx++];
  return 0;
}

int DS_hub_api_usart_tx_event_mediator(hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  if(!ptr_pkt){
      return 1;
  }

  unsigned int i = 0;
  for(i = 0; i < usart_tx_cmd_num; i++){
      if(ds_hub_api_tx_fcode_table[i].fcode == ptr_pkt->fcode){
          break;
      }
  }

  if(i == usart_tx_cmd_num){
      return 2;
  }
  if(hub_log_enable){
      pkt_tx_count++;
      DS_app_log_error("tx pkt %ld, seq %02x, fcode %02x\r\n",pkt_tx_count, ptr_pkt->seq, ptr_pkt->fcode);
  }
  return ds_hub_api_tx_fcode_table[i].fun(ptr_pkt, waitack);
}

bool check_usart_active_evt_is_finish(HUB_API_USART_MSG_FCODE_E fcode)
{
  bool bret = true;
  switch(fcode){
    case H_TO_P_EVENT_HUB_EVENT:
      bret = check_hub_event_is_finsih();
      break;
    case H_TO_P_EVENT_RFM_EVENT:
      bret = check_rfm_event_is_finsih();
      break;
    case H_TO_P_EVENT_FILE_TRANSFER:
      bret = check_file_event_is_finsih();
      break;
    default:
      break;
  }
  return bret;
}

void clean_usart_active_evt_tns_flag(HUB_API_USART_MSG_FCODE_E fcode)
{
  unsigned char tns = 0;
  unsigned char flag = 0;

  switch(fcode){
    case H_TO_P_EVENT_HUB_EVENT:
      setThisParam(ENbyEvtA0TNS, (unsigned char *)&tns);
      setThisParam(ENbyEvtA0AckFlag, (unsigned char *)&flag);
      break;
    case H_TO_P_EVENT_RFM_EVENT:
      setThisParam(ENbyEvtA1TNS, (unsigned char *)&tns);
      setThisParam(ENbyEvtA1AckFlag, (unsigned char *)&flag);
      break;
    case H_TO_P_EVENT_FILE_TRANSFER:
      setThisParam(ENbyEvtA2TNS, (unsigned char *)&tns);
      setThisParam(ENbyEvtA2AckFlag, (unsigned char *)&flag);
      break;
    default:

      break;
  }

}

void usart_tx_msg(const hub_api_usart_msg_t *ptr_pkt, int data_len)
{
  //调用串口环形队列，发送
  (void)ptr_pkt;
#ifdef BSP_ENABLE_COM
  int i = 0;
  memset(usart_tx_buffer, 0, sizeof(usart_tx_buffer));
  usart_tx_len = 0;
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->stx;
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->seq;
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->len;
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->statu;
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->fcode;
  for(i = 0; i < data_len; i++){
      usart_tx_buffer[usart_tx_len++] = ptr_pkt->data.data[i];
  }
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->crc[0];
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->crc[1];
  usart_tx_buffer[usart_tx_len++] = ptr_pkt->etx;

  DS_com_Txbuff((char *)usart_tx_buffer, usart_tx_len);
#else
  (void) data_len;
  printf_pkt(ptr_pkt);
#endif
}

HUB_API_WEAK int tx_set_init(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_init_data.error_code;
  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  if(init_reboot){
      set_reset_enable(1);
  }else{
      DS_hub_api_creat_hub_event(NEED_SYNC_PRM, NULL, 0);
  }
  return 0;
}

HUB_API_WEAK int tx_set_rfm_qrfh(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_rfm_qrfh_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_set_rfm_qrfh_batch(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_rfm_qrfh_batch_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_set_rfm_status_model(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_rfm_status_model_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_set_rfm_operate_model(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_rfm_operate_model_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_set_rfm_sync_option_batch(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_rfm_sync_option_batch_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_set_rfm_sync_qrfh_batch(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_rfm_sync_qrfh_batch_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_set_hub_reset(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_set_hub_reset_data.error_code;
  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  set_reset_enable(1);
  return 0;
}


HUB_API_WEAK int tx_get_registered_rfm_info(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_get_registered_rfm_data.info;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_get_specific_rfm_info(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_get_specific_rfm_info_data.qrfr1;
  (void)ptr_pkt->data.tx_get_specific_rfm_info_data.qrfr2;
  (void)ptr_pkt->data.tx_get_specific_rfm_info_data.qrfh1;
  (void)ptr_pkt->data.tx_get_specific_rfm_info_data.qrfh2;
  (void)ptr_pkt->data.tx_get_specific_rfm_info_data.option;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_get_hub_physical(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_get_hub_physical_data.t_integer;
  (void)ptr_pkt->data.tx_get_hub_physical_data.v_decimal;
  (void)ptr_pkt->data.tx_get_hub_physical_data.t_integer;
  (void)ptr_pkt->data.tx_get_hub_physical_data.t_decimal;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_get_hub_rssi(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_get_hub_rssi_data.real_rssi;
  (void)ptr_pkt->data.tx_get_hub_rssi_data.avg_rssi;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_get_hub_ver(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_get_hub_ver_data.version_1;
  (void)ptr_pkt->data.tx_get_hub_ver_data.version_2;
  (void)ptr_pkt->data.tx_get_hub_ver_data.version_3;
  (void)ptr_pkt->data.tx_get_hub_ver_data.yy;
  (void)ptr_pkt->data.tx_get_hub_ver_data.mm;
  (void)ptr_pkt->data.tx_get_hub_ver_data.dd;
  (void)ptr_pkt->data.tx_get_hub_ver_data.no;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_local_register(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_local_register_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_mac_register(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_mac_register_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_qrcode_register(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_qrcode_register_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_sync_broadcast(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_sync_broadcast_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_normal_broadcast(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_normal_broadcast_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_point_to_point(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_point_to_point_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_delete_rfm(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_delete_rfm_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_start_ota(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_start_ota_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_sn_register(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_sn_register_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_file_transport(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_file_transport_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_choose_ant(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_choose_ant_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_stop_sync_broadcast(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_stop_sync_broadcast_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_do_test(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_do_test_data.error_code;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}

HUB_API_WEAK int tx_event_hub_event(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  unsigned char tns = 0;
  unsigned char flag = 0;

  (void)ptr_pkt->data.tx_event_hub_event_data.event_type;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));

  getThisParam(ENbyEvtA0TNS, (unsigned char *)&tns);
  if(tns == 0){
      flag = 1;
      setThisParam(ENbyEvtA0AckFlag, (unsigned char *)&flag);
  }
  tns++;
  setThisParam(ENbyEvtA0TNS, (unsigned char *)&tns);

  if(check_hub_event_need_rtns()){
      *waitack = 1;
  }else{
      *waitack = 0;
      tns = 0;
      flag = 0;
      setThisParam(ENbyEvtA0TNS, (unsigned char *)&tns);
      setThisParam(ENbyEvtA0AckFlag, (unsigned char *)&flag);
  }
  return 0;
}

HUB_API_WEAK int tx_event_rfm_event(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  unsigned char tns = 0;
  unsigned char flag = 0;
  unsigned char mode = 0;
  (void)ptr_pkt->data.tx_event_rfm_event_data.rolling_code;
  (void)ptr_pkt->data.tx_event_rfm_event_data.rssi;
  (void)ptr_pkt->data.tx_event_rfm_event_data.debug_info;
  (void)ptr_pkt->data.tx_event_rfm_event_data.cmd;
  //(void)ptr_pkt->data.tx_event_rfm_event_data.data;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));

  getThisParam(ENbyPanelSetOtaMode, (unsigned char *)&mode); //OTA时，A1事件不再等应答
  if(mode == OTA_MODE_OTA_ING){
      *waitack = 0;
      return 0;
  }

  getThisParam(ENbyEvtA1TNS, (unsigned char *)&tns);
  if(tns == 0){
      flag = 1;
      setThisParam(ENbyEvtA1AckFlag, (unsigned char *)&flag);
  }
  tns++;
  setThisParam(ENbyEvtA1TNS, (unsigned char *)&tns);

  if(check_rfm_event_need_rtns()){
      *waitack = 1;
  }else{
      *waitack = 0;
      tns = 0;
      flag = 0;
      setThisParam(ENbyEvtA1TNS, (unsigned char *)&tns);
      setThisParam(ENbyEvtA1AckFlag, (unsigned char *)&flag);
  }
  return 0;
}

HUB_API_WEAK int tx_event_file_event(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  unsigned char tns = 0;
  unsigned char flag = 0;

  (void)ptr_pkt->data.tx_event_file_event_data.event_type;
  (void)ptr_pkt->data.tx_event_file_event_data.data;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  getThisParam(ENbyEvtA2TNS, (unsigned char *)&tns);
  if(tns == 0){
      flag = 1;
      setThisParam(ENbyEvtA2AckFlag, (unsigned char *)&flag);
  }
  tns++;
  setThisParam(ENbyEvtA2TNS, (unsigned char *)&tns);

  if(check_file_event_need_rtns()){
      *waitack = 1;
  }else{
      *waitack = 0;
      tns = 0;
      flag = 0;
      setThisParam(ENbyEvtA2TNS, (unsigned char *)&tns);
      setThisParam(ENbyEvtA2AckFlag, (unsigned char *)&flag);
  }
  return 0;
}

HUB_API_WEAK int tx_event_rfm_debug_event(const hub_api_usart_msg_t *ptr_pkt, unsigned char *waitack)
{
  (void)ptr_pkt->data.tx_event_rfm_debug_event_data.rolling_code;
  (void)ptr_pkt->data.tx_event_rfm_debug_event_data.rssi;
  (void)ptr_pkt->data.tx_event_rfm_debug_event_data.debug_info;
  (void)ptr_pkt->data.tx_event_rfm_debug_event_data.cmd;

  usart_tx_msg(ptr_pkt, (ptr_pkt->len - HUB_API_USART_MSG_LEN_MIN_VALUE));
  *waitack = 0;
  return 0;
}
